﻿/*
更新日志：
  2022.05.08
    移除部分废弃的参数。
    为界面改色扫清了障碍。
    重构 以指定代码页计算匹配对象位置及长度()
    版本号1.5.1。

  2022.04.07
    修复参考窗口中两个错误的正则示例。
    版本号1.5。

  2021.11.15
    窗口失去焦点时自动关闭提示框。
    版本号1.42。

  2021.11.06
    修改 中文帮助文件 位置。
    版本号1.41。

  2021.10.22
    改变 Include 方式，降低库冲突的可能性。
    版本号1.4。

  2021.08.17
    修复H版不能运行的问题。
    版本号1.3。

  2021.08.05
    提升界面缩放速度。
    修复界面缩放闪烁。
    增加多处说明信息。
    使用 btt 显示信息。
    完成高级模式的合并。
    优化软件启动后的默认示例。
    实现正则选项的唯一化添加。
    参考信息插入模式改为替换。
    版本号1.2。

  2021.07.17
    当正则表达式末尾有空行时进行提示。
    版本号1.1。

  2021.07.11
    兼容模式生效。
    兼容模式提供说明。
    生成代码按钮生效。
    优化文件目录结构。
    参考按钮中的示例全部生效。
    删除参考按钮中的过时示例。
    更改软件启动后的默认示例。
    处理正则中零宽匹配的问题。
    强制 U32 模式运行避免出错。
    版本号1.0。

  2021.07.07
    错字修改。
    版本号0.4。

  2020.09.07
    界面优化。
    增加主页按钮。
    版本号0.3。

  2020.07.30
    界面可适应系统缩放参数。
    版本号0.2。

已知问题：
  1.极限情况下高亮存在性能及闪烁问题
    SCITE 在高亮一次文本后
    高亮一直是跟随着文本的
    比如 abc book bcd
    高亮了 book 后 即使变为 books
    book 的高亮依然存在
  2.快速切换起点可能导致高亮出错

todo：
  设置焦点在匹配处

*/

#NoEnv
#Requires AutoHotkey v1.1.33+

#Include <SCI>                    ; 因为定义了很多全局变量,所以必须放前面. 否则涉及到使用了全局变量的地方,就会不起作用

RunWith(,"U32")                   ; 因为 dll 是32位的，所以必须强制指定运行版本。

初始正则框内容:="^a(bc)(d)(.+)"   ; 注意如果添加的内容为纯数字,将无法添加. 应该是 SCI 库文件的一个 BUG
初始文本框内容=                   ; 注意使用此种方式添加的文本段落,如果不用 Join 指定链接符的话,默认链接符是 `n. 而正则中对换行的处理默认是 `r`n ,所以会导致问题
(Join`r`n
ABcde
abcde
abcdef
abcdefg

-------------说明--------------

相邻匹配的颜色总不相同

亮黄色块 代表第1个匹配
暗黄色块 代表第2个匹配
亮黄色块 代表第3个匹配

红色字符 代表第1个子模式匹配
绿色字符 代表第2个子模式匹配
红色字符 代表第3个子模式匹配

以此类推
)
gosub, 界面  ; 创建主界面
gosub, 实时响应
return

; 此标签的作用就是获取文本和正则并高亮结果
实时响应:
  Gui, Submit, NoHide                     ; 获取 Gui 控件状态

  正则:=""
  文本:=""
  原始匹配对象:=""                        ; 此对象中存储原始匹配对象. 主要用于调试和扩展
  匹配对象:=""                            ; 此对象中存储原始匹配对象格式化并重算后的坐标,长度,值,名字. 使用前先清空,避免混乱
  全局索引:=""
  高亮风格:=""

  sci1.GetText(sci1.getLength()+1, 正则)  ; 获取正则
  sci2.GetText(sci2.getLength()+1, 文本)  ; 获取文本
  ; sci2.ClearDocumentStyle()             ; 清空高亮. 此种方式会导致自动换行或不换行均出现问题!!!
  sci2.StartStyling(0)                    ; 这里的0是坐标。 StartStyling() 必须在前
  , sci2.SetStyling(sci2.getLength(), 0)  ; 使用样式0，从坐标0开始重绘所有文本，起清空高亮的作用

  if (兼容模式=1)
    正则:=RegEx.AddOptions(正则, "m", "(*ANYCRLF)")
  if (不区分大小写=1)
    正则:=RegEx.AddOptions(正则, "i")
  if (句点全匹配=1)
    正则:=RegEx.AddOptions(正则, "s")
  if (非贪婪模式=1)
    正则:=RegEx.AddOptions(正则, "U")

  if (全局模式=1)
    原始匹配对象:=RegEx.GlobalMatch(文本, 正则, 起点)
  else
    原始匹配对象:=RegEx.Match(文本, 正则, 起点)

  if (RegExMatch(正则, "\R$"))
    btt("检测到当前 “正则表达式” 末尾存在空行`r`n若末尾的空行是误操作请自行删除`r`n因为空行可能会影响匹配结果",,, 3, "Style3")
  else
    btt(,,, 3)

  匹配对象:=以指定代码页计算匹配对象位置及长度(文本, 原始匹配对象, "UTF-8")
  loop, % 匹配对象["GlobalCount"]
  {
    全局索引:=A_Index
    高亮风格:=Mod(全局索引, 2)=1 ? 0 : 3  ; 高亮风格总是为 0 或 3 , SCE_AHKL_LPPDEFINED1+3=SCE_AHKL_LPPDEFINED4. 即 全局1高亮风格+3=全局2高亮风格

    sci2.StartStyling(匹配对象[全局索引]["Pos"][0])  ; 整体高亮. 之所以设置 6种 高亮风格,是为了完美区隔每个整体及其子模式
    , sci2.SetStyling(匹配对象[全局索引]["Len"][0], SCE_AHKL_LPPDEFINED1+高亮风格)
    loop, % 匹配对象[全局索引]["Count"]
    {
      if (Mod(A_Index, 2)=1)
        sci2.StartStyling(匹配对象[全局索引]["Pos"][A_Index])				; 子模式1 高亮
        , sci2.SetStyling(匹配对象[全局索引]["Len"][A_Index], SCE_AHKL_LPPDEFINED2+高亮风格)
      else
        sci2.StartStyling(匹配对象[全局索引]["Pos"][A_Index])				; 子模式2 高亮
        , sci2.SetStyling(匹配对象[全局索引]["Len"][A_Index], SCE_AHKL_LPPDEFINED3+高亮风格)
    }
  }
return

#Include <BTT>
#Include <RunWith>
#Include <RegEx>  ; H 版中，如果本地库和用户库有相同中文名称库文件，则会报函数重复引用错误。L 版没这问题，因此改名。
#Include <以指定代码页计算匹配对象位置及长度>

#Include <主界面>
#Include <智能库引用>
#Include <参考按钮菜单项>